package com.origin.learn.dbpool;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.BlockingQueue;

/**
 * @Description: 连接池的抽象类，实现了一些通用方法
 * @Date: 2020/2/28
 * @Time: 16:12
 * @Created by:   dingtao
 * @Modified by:
 * @Modified at:
 */
public abstract class AbstractConnectionPool implements ConnectionPool, Runnable {


    @Override
    public abstract int getInitSize();

    @Override
    public abstract int getMaxSize();

    @Override
    public abstract int getCoreSize();

    @Override
    public int getActiveCount(){
        synchronized (this) {
            return getPool().size();
        }
    }

    @Override
    public Connection getConnection(){
        Connection connection;
        synchronized (this){
            while (true) {
                try {
                    connection = getPool().take();
                    if (connection.isValid(1000)){
                        break;
                    }else {
                        connection.close();
                    }
                }catch (SQLException e){
                    e.printStackTrace();
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
        System.out.println("获取到了一个连接，当前剩余连接数:"+getActiveCount());
        return connection;
    }

    @Override
    public boolean putBackConnection(Connection connection) {
        synchronized (this){
            if (getActiveCount()<getMaxSize()){
                getPool().offer(connection);
                System.out.println("放进了一个连接，当前剩余连接数:"+getActiveCount());
                return true;
            }
            System.out.println("连接池数量已满，放回失败，当前剩余连接数:"+getActiveCount());
            return false;
        }
    }

    @Override
    public abstract Connection createConnection();

    @Override
    public abstract BlockingQueue<Connection> getPool();

    @Override
    public abstract long getCheckIntervalTime();

    @Override
    public abstract boolean isAlive();

    @Override
    public abstract void kill();

    @Override
    public void run() {
        while (isAlive() && !Thread.currentThread().isInterrupted()) {
            try {
                Thread.sleep(getCheckIntervalTime());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (this) {
                System.out.println("自动监控开始,当前连接数量:"+getActiveCount());
                if (!isAlive()){
                    break;
                }
                int activeCount = getActiveCount();
                if (activeCount < getCoreSize()) {
                    for (int i = 0; i < getCoreSize()-activeCount; i++) {
                        Connection connection = createConnection();
                        getPool().offer(connection);
                    }
                }

                System.out.println("自动监控结束,当前连接数量:"+getActiveCount());
            }
        }
    }

}
